#include <stdio.h>
#include "csb.h"
#include "err.h"
#include "convex_polygon.h"
#include "coord.h"
#include "csnode.h"
#include "csbmath.h"

static int show_objdataname(void** datare, void* ctlflag)
{
	csobjdata_t* pobj = (csobjdata_t*)(*datare);
	printf("\tobj name = %s\n", pobj->name);
	return 1;
}
static void cpprint(convex_polygon_t* ppo)
{
	uint32_t n = 0;
	printf("######...#######\n");
	for (n = 0; n < ppo->pnum; ++n) {
		printf("%.2f, %.2f\n", ppo->points[n].x, ppo->points[n].y);
	}
	printf("######...#######\n");
}

/*********************| tests |*********************/

static void test_loadcsb()
{
	printf("###############| test load csb |################\n");
	list_t* objlist = load_csb("good4.csb");
	if (!objlist) {
		printf("%s\n", csb_lasterr());
		return;
	}
	printf("load csb success, get %u obj \n", objlist->size);
	list_foreach(objlist, show_objdataname, NULL);
	list_free(objlist, (free_node_data)csobjdata_free);
}

static void test_polygon()
{
	printf("*********************| check polygon |*********************\n");
	pos_t p = {1, 1};
	CP_STACK_4(cp1);
	cp1.pnum = 4;
	cp1.points[0].x = 1; cp1.points[0].y = 1;
	cp1.points[1].x = 1; cp1.points[1].y = -1;
	cp1.points[2].x = -1; cp1.points[2].y = -1;
	cp1.points[3].x = -1; cp1.points[3].y = 1;
	if (point_in_CP(&p, &cp1)) {
		printf("point(%.2f, %.2f) in cp1\n", p.x, p.y);
	} else {
		printf("point(%.2f, %.2f) not in cp1\n", p.x, p.y);
	}
	printf("----------------------------------------\n");
	p.x = 1; p.y =20;
	if (point_in_CP(&p, &cp1)) {
		printf("point(%.2f, %.2f) in cp1\n", p.x, p.y);
	} else {
		printf("point(%.2f, %.2f) not in cp1\n", p.x, p.y);
	}
	printf("----------------------------------------\n");
	p.x = 0;p.y =0 ;
	if (point_in_CP(&p, &cp1)) {
		printf("point(%.2f, %.2f) in cp1\n", p.x, p.y);
	} else {
		printf("point(%.2f, %.2f) not in cp1\n", p.x, p.y);
	}
	printf("----------------------------------------\n");
	p.x = 1;p.y = 2;
	if (point_in_CP(&p, &cp1)) {
		printf("point(%.2f, %.2f) in cp1\n", p.x, p.y);
	} else {
		printf("point(%.2f, %.2f) not in cp1\n", p.x, p.y);
	}

	CP_STACK_4(cp2);
	cp2.pnum = 4;
	cp2.points[0].x = 1; cp2.points[0].y = 2;
	cp2.points[1].x = 2; cp2.points[1].y = 1;
	cp2.points[2].x = 3; cp2.points[2].y = -1;
	cp2.points[3].x = 2; cp2.points[3].y = -1;
	if (CP_love_CP(&cp1, &cp2)) {
		printf("cp1 love cp2 \n");
	} else {
		printf("cp1 hate cp2 \n");
	}
}

static void test_elepolygon()
{
	printf("####################| test get ele polygon |############\n");
	elebase_t ele = {{0, 0}, 1.0f, 1.0f, 0};
	CP_STACK_4(p4);
	p4.pnum = 4;
	p4.points[0].x = 20; p4.points[0].y = 20;
	p4.points[1].x = 20; p4.points[1].y = -20;
	p4.points[2].x = -20; p4.points[2].y = -20;
	p4.points[3].x = -20; p4.points[3].y = 20;
	printf("origin polygon:\n");
	cpprint(&p4);

	CP_STACK_4(mycp);
	elebase_coll_CP(&ele, &p4, &mycp);
	printf("get polygon 0:\n");
	cpprint(&mycp);

	ele.pos.x += 2;
	ele.pos.y += 2;
	elebase_coll_CP(&ele, &p4, &mycp);
	printf("get polygon move 1:\n");
	cpprint(&mycp);

	ele.scale.xs = 1.5f;
	ele.scale.ys = 2.5f;
	elebase_coll_CP(&ele, &p4, &mycp);
	printf("get polygon scale 2:\n");
	cpprint(&mycp);

	ele.rotate = 405;
	elebase_coll_CP(&ele, &p4, &mycp);
	printf("get polygon rotate 2:\n");
	cpprint(&mycp);
}

static void test_math( )
{
	printf("%f\n", CSB_angle_normalize_180(240.0f));
	printf("%f\n", CSB_angle_normalize_360(760.0f));
	float ax = 100.0f;
	float ay = 20.0f;
	for (int i = 0; i < 100000; ++i) {
		CSB_rotate(&ax, &ay, 30.0f + i);
	}
}

#include <sys/time.h>

int main(void)
{
	CSB_math_init();

	struct timeval __testval;
	struct timeval ttmp;
	gettimeofday(&__testval, NULL);

	test_math();

	gettimeofday(&ttmp, NULL);
	printf("time use: %lu\n", (ttmp.tv_sec - __testval.tv_sec) * 1000000 + ttmp.tv_usec - __testval.tv_usec);

	test_polygon();
	return 0;
	test_elepolygon();

	/* first of all */
	COORD_CONFIG_VIEW_WORLD(800, 480);
	list_buf_init();
	csnode_buf_init();
	csobj_buf_init();
	test_loadcsb();
	/* end of all */
	csnode_buf_end(false);
	csobj_buf_end(false);
	return 0;
}

